package cn.stylefeng.guns.modular.car.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.modular.car.pojo.request.ExcelRequest;
import cn.stylefeng.guns.modular.car.pojo.response.CarResponse;
import cn.stylefeng.guns.modular.car.pojo.response.CountResponse;
import cn.stylefeng.guns.modular.car.util.ExcelFillCellMergePrevColUtils;
import cn.stylefeng.guns.modular.car.util.ExcelFillCellMergeStrategyUtils;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.guns.modular.car.entity.Car;
import cn.stylefeng.guns.modular.car.enums.CarExceptionEnum;
import cn.stylefeng.guns.modular.car.mapper.CarMapper;
import cn.stylefeng.guns.modular.car.pojo.request.CarRequest;
import cn.stylefeng.guns.modular.car.service.CarService;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;

import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData;
import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.read.listener.ReadListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;
import java.math.BigDecimal;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 业务实现层
 *
 * @author xbz
 * @date 2023/04/07 14:21
 */
@Service
public class CarServiceImpl extends ServiceImpl<CarMapper, Car> implements CarService {

    @Resource
    private CarMapper carMapper;
	@Override
    public void add(CarRequest carRequest) {
        Car car = new Car();
        BeanUtil.copyProperties(carRequest, car);
        this.save(car);
    }

    @Override
    public void del(CarRequest carRequest) {
        Car car = this.queryCar(carRequest);
        this.removeById(car.getId());
    }

    @Override
    public void edit(CarRequest carRequest) {
        Car car = this.queryCar(carRequest);
        BeanUtil.copyProperties(carRequest, car);
        this.updateById(car);
    }

    @Override
    public Car detail(CarRequest carRequest) {
        return this.queryCar(carRequest);
    }

    @Override
    public PageResult<Car> findPage(CarRequest carRequest) {
        LambdaQueryWrapper<Car> wrapper = createWrapper(carRequest);
        Page<Car> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);
        return PageResultFactory.createPageResult(sysRolePage);
    }

    @Override
    public PageResult<CarResponse> selectPage(String name, Integer pageNo, Integer pageSize) {
        List<CarResponse> carResponses = this.baseMapper.selectPage(name);
        return PageResultFactory.createPageResult(carResponses,carResponses.stream().count(),pageSize,pageNo);
    }

    @Override
    public void importExcel(MultipartFile file, HttpServletResponse response) {

        //1.验证
        if(!file.isEmpty()){
            try{
                List<ExcelRequest> list=new ArrayList<>();
                EasyExcel.read(file.getInputStream(),ExcelRequest.class, new ReadListener<ExcelRequest>() {

                    @Override
                    public void onException(Exception exception, AnalysisContext context) throws Exception {

                    }

                    @Override
                    public void invokeHead(Map<Integer, CellData> headMap, AnalysisContext context) {

                    }

                    @Override
                    public void invoke(ExcelRequest ce, AnalysisContext analysisContext) {
                        //校验
                        Car car=new Car();
                        BeanUtils.copyProperties(ce,car);

                        if(carMapper.insert(car)>0){
                            ce.setResult("导入成功");
                        }else {
                            ce.setResult("导入失败");
                        }
                        list.add(ce);
                    }

                    @Override
                    public void extra(CellExtra extra, AnalysisContext context) {

                    }

                    @Override
                    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

                    }

                    @Override
                    public boolean hasNext(AnalysisContext context) {
                        return true;
                    }
                }).sheet().doRead();

                //写出 下载
                response.setHeader("Content-Disposition", "attachment;filename="+System.currentTimeMillis()+"-CarResult.xlsx");
                EasyExcel.write(response.getOutputStream(),ExcelRequest.class).sheet().doWrite(list);
            }
            catch (Exception ex){

            }
        }
    }

    @Override
    public void exportExcel(HttpServletResponse response) throws IOException {
        //设置第几列开始合并
        int[] mergeColumnIndex = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        //设置第几行开始合并
        int mergeRowIndex = 1;
        ExcelFillCellMergePrevColUtils excelFillCellMergePrevColUtils = new ExcelFillCellMergePrevColUtils();
        ExcelFillCellMergeStrategyUtils excelFillCellMergeStrategyUtils = new ExcelFillCellMergeStrategyUtils(mergeRowIndex, mergeColumnIndex);
        List<CarResponse> list = carMapper.selectPage(null);
        response.setHeader("Content-Disposition", "attachment;filename="+System.currentTimeMillis()+"-CarList.xlsx");
        EasyExcel
                .write(response.getOutputStream(),CarResponse.class)
                .registerWriteHandler(excelFillCellMergePrevColUtils)
                .registerWriteHandler(excelFillCellMergeStrategyUtils)
                .sheet()
                .doWrite(list);
    }

    @Override
    public List<Object> carCount() {
        List<CountResponse> count = carMapper.count();
        List<String> names = count.stream().map(CountResponse::getName).collect(Collectors.toList());
        List<Integer> nums = count.stream().map(CountResponse::getNum).collect(Collectors.toList());
        List<Object> list = new ArrayList<>();
        list.add(names);
        list.add(nums);
        return list;
    }

    @Override
    public List<Car> findList(CarRequest carRequest) {
        LambdaQueryWrapper<Car> wrapper = this.createWrapper(carRequest);
        return this.list(wrapper);
    }

    /**
     * 获取信息
     *
     * @author xbz
     * @date 2023/04/07 14:21
     */
    private Car queryCar(CarRequest carRequest) {
        Car car = this.getById(carRequest.getId());
        if (ObjectUtil.isEmpty(car)) {
            throw new ServiceException(CarExceptionEnum.CAR_NOT_EXISTED);
        }
        return car;
    }

    /**
     * 创建查询wrapper
     *
     * @author xbz
     * @date 2023/04/07 14:21
     */
    private LambdaQueryWrapper<Car> createWrapper(CarRequest carRequest) {
        LambdaQueryWrapper<Car> queryWrapper = new LambdaQueryWrapper<>();

        Integer id = carRequest.getId();
        String name = carRequest.getName();
        Integer brandId = carRequest.getBrandId();
        Long uid = carRequest.getUid();
        String gb = carRequest.getGb();
        BigDecimal price = carRequest.getPrice();
        String buyDate = carRequest.getBuyDate();

        queryWrapper.eq(ObjectUtil.isNotNull(id), Car::getId, id);
        queryWrapper.like(ObjectUtil.isNotEmpty(name), Car::getName, name);
        queryWrapper.like(ObjectUtil.isNotEmpty(brandId), Car::getBrandId, brandId);
        queryWrapper.eq(ObjectUtil.isNotNull(uid), Car::getUid, uid);
        queryWrapper.like(ObjectUtil.isNotEmpty(gb), Car::getGb, gb);
        queryWrapper.eq(ObjectUtil.isNotNull(price), Car::getPrice, price);
        queryWrapper.eq(ObjectUtil.isNotNull(buyDate), Car::getBuyDate, buyDate);

        return queryWrapper;
    }

}